home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Apple II Sample Code / MPW IIGS SC / SC.021.Dynamo / dynamo.includes / rt.macros < prev    next >
Encoding:
Text File  |  1990-06-24  |  39.7 KB  |  1,810 lines  |  [TEXT/MPS ]

  1. *******************************************************
  2. *                        *
  3. * DYNAMO                        *
  4. *                        *
  5. * Apple II 8-bit runtime macros.            *
  6. * Copyright (C) 1990 Apple Computer.        *
  7. * Version 3.1                    *
  8. *                        *
  9. * Written by Eric Soldan, Apple II DTS        *
  10. *                                                     *
  11. * Developer Technical Support Apple II Sample Code    *
  12. *                                                     *
  13. *******************************************************
  14.  
  15. * These macros are interfaces for the runtime routines associated with them.
  16. * The runtime routines handle up to 128 integer variables, and up to 256
  17. * strings.  The integer functions are simple add,sub,mul,div, and others.
  18. * These others include mass-initialization, min, max, print decimal, etc.
  19. * The string functions are most of what is available in AppleSoft, in
  20. * various forms.  There is also support for multi-dimension arrays.
  21.  
  22. * The principle of the runtime routines is that the xreg holds a destination
  23. * variable number (for ints: 0-254, for strings: 0-255).  All runtimes preserve
  24. * the xreg, therefore, you can do multiple operations to a single variable
  25. * without having to reload the xreg.  The values that are used on the xreg
  26. * variable (the source data), is one of 3 forms for integers:
  27. *    1. 1-byte value
  28. *    2. 2-byte value
  29. *    3. 2-byte integer variable.
  30. * 1-byte values are placed in the acc.  2-byte values are placed in the acc,y
  31. * (acc=lo, y=hi).  2-byte integer variables have the variable number placed in
  32. * the yreg.  (The yreg is not preserved by the runtime routines.)
  33. * Once the source data is loaded (in acc, acc-y, or y), the proper call to the
  34. * runtime routines is made.  The 'proper' routine is based on the type of data
  35. * the source is.  (If the source is a variable, and we are adding, the macro
  36. * will call the addvar routine.)
  37.  
  38. * Strings are also referenced by number.  There are 3 tables for strings:
  39. *    1. String length table.
  40. *    2. Max string length table.
  41. *    3. Pointer table.
  42. * So, each string takes up four bytes, plus however long the max string length
  43. * is.  Having the pointer allows the program to point into memory that was
  44. * never loaded or initialized.  This can save time loading the application from
  45. * disk.  The string routines will never overwrite the buffer space alloced for
  46. * them.  The string will be truncated.  So, you can append strings without
  47. * worry about clobbering memory.
  48.  
  49.  
  50. *****************************************************************
  51. *****************************************************************
  52. *****************************************************************
  53.  
  54. * These macros are called by other macros in this file.
  55.  
  56. ***************************************
  57.  
  58.     MACRO
  59.     acorm    &op
  60.     lclc    &str
  61. &str    setc    &op
  62.     if    &substr(&str,1,1)='#' goto .imm
  63.     if    &substr(&str,1,1)<>'*' then
  64.     aerror    'non-variable parameter must start with a # or *'
  65.     mexit
  66.     endif
  67. &str    setc    &substr(&str,2,999)
  68.     lcla    &deref
  69. &deref    seta    0
  70. .a    if    &substr(&str,1,1)<>'*' goto .b
  71. &str    setc    &substr(&str,2,999)
  72. &deref    seta    &deref+1
  73.     goto    .a
  74. .b    if    &substr(&str,1,1)='<' then
  75. &str    setc    &substr(&str,2,999)
  76.     endif
  77.     if    &deref>0 then
  78.     lda    &str+1
  79.     sta    aderefz+2
  80.     endif
  81.     lda    &str
  82. .d    if    &deref>0 then
  83.     jsr    aderef
  84. &deref    seta    &deref-1
  85.     goto    .d
  86.     endif
  87.     mexit
  88. .imm
  89. &str    setc    &substr(&str,2,999)
  90.     if    &substr(&str,1,1)='<' then
  91. &str    setc    &substr(&str,2,999)
  92.     endif
  93.     lda    #<&str
  94.     MEND
  95.  
  96. ***************************************
  97.  
  98.     MACRO
  99.     xcorm    &op
  100.     lclc    &str
  101. &str    setc    &op
  102.     if    &substr(&str,1,1)='#' goto .imm
  103.     if    &substr(&str,1,1)<>'*' then
  104.     aerror    'non-variable parameter must start with a # or *'
  105.     mexit
  106.     endif
  107. &str    setc    &substr(&str,2,999)
  108.     lcla    &deref
  109. &deref    seta    0
  110. .a    if    &substr(&str,1,1)<>'*' goto .b
  111. &str    setc    &substr(&str,2,999)
  112. &deref    seta    &deref+1
  113.     goto    .a
  114. .b    if    &substr(&str,1,1)='<' then
  115. &str    setc    &substr(&str,2,999)
  116.     endif
  117.     if    &deref>0 then
  118.     ldx    &str+1
  119.     stx    xderefz+2
  120.     endif
  121.     ldx    &str
  122. .d    if    &deref>0 then
  123.     jsr    xderef
  124. &deref    seta    &deref-1
  125.     goto    .d
  126.     endif
  127.     mexit
  128. .imm
  129. &str    setc    &substr(&str,2,999)
  130.     if    &substr(&str,1,1)='<' then
  131. &str    setc    &substr(&str,2,999)
  132.     endif
  133.     ldx    #<&str
  134.     MEND
  135.  
  136. ***************************************
  137.  
  138.     MACRO
  139.     ycorm    &op
  140.     lclc    &str
  141. &str    setc    &op
  142.     if    &substr(&str,1,1)='#' goto .imm
  143.     if    &substr(&str,1,1)<>'*' then
  144.     aerror    'non-variable parameter must start with a # or *'
  145.     mexit
  146.     endif
  147. &str    setc    &substr(&str,2,999)
  148.     lcla    &deref
  149. &deref    seta    0
  150. .a    if    &substr(&str,1,1)<>'*' goto .b
  151. &str    setc    &substr(&str,2,999)
  152. &deref    seta    &deref+1
  153.     goto    .a
  154. .b    if    &substr(&str,1,1)='<' then
  155. &str    setc    &substr(&str,2,999)
  156.     endif
  157.     if    &deref>0 then
  158.     ldy    &str+1
  159.     sty    yderefz+2
  160.     endif
  161.     ldy    &str
  162. .d    if    &deref>0 then
  163.     jsr    yderef
  164. &deref    seta    &deref-1
  165.     goto    .d
  166.     endif
  167.     mexit
  168. .imm
  169. &str    setc    &substr(&str,2,999)
  170.     if    &substr(&str,1,1)='<' then
  171. &str    setc    &substr(&str,2,999)
  172.     endif
  173.     ldy    #<&str
  174.     MEND
  175.  
  176. ***************************************
  177.  
  178.     MACRO
  179.     axcorm    &op
  180. axisbyte    set    0
  181.     lclc    &str
  182. &str    setc    &op
  183.     if    &substr(&str,1,1)='#' goto .imm
  184.     if    &substr(&str,1,1)<>'*' then
  185.     aerror    'non-variable parameter must start with a # or *'
  186.     mexit
  187.     endif
  188. &str    setc    &substr(&str,2,999)
  189.     lcla    &deref
  190. &deref    seta    0
  191. .a    if    &substr(&str,1,1)<>'*' goto .b
  192. &str    setc    &substr(&str,2,999)
  193. &deref    seta    &deref+1
  194.     goto    .a
  195. .b    if    &substr(&str,1,1)='<' then
  196. axisbyte    set    1
  197. &str    setc    &substr(&str,2,999)
  198.     endif
  199.     lda    &str
  200.     if    &deref>0 goto .c
  201.     if    axisbyte=1 goto .d
  202. .c    ldx    &str+1
  203. .d    if    &deref>0 then
  204.     jsr    deref
  205. &deref    seta    &deref-1
  206.     goto    .d
  207.     endif
  208.     mexit
  209. .imm
  210. &str    setc    &substr(&str,2,999)
  211.     if    &substr(&str,1,1)='<' then
  212. axisbyte    set    1
  213. &str    setc    &substr(&str,2,999)
  214.     endif
  215.     lda    #<&str
  216.     if    axisbyte=0 then
  217.     ldx    #>&str
  218.     endif
  219.     MEND
  220.  
  221. ***************************************
  222.  
  223.     MACRO
  224.     aycorm    &op
  225. ayisbyte    set    0
  226.     lclc    &str
  227. &str    setc    &op
  228.     if    &substr(&str,1,1)='#' goto .imm
  229.     if    &substr(&str,1,1)<>'*' then
  230.     aerror    'non-variable parameter must start with a # or *'
  231.     mexit
  232.     endif
  233. &str    setc    &substr(&str,2,999)
  234.     lcla    &deref
  235. &deref    seta    0
  236. .a    if    &substr(&str,1,1)<>'*' goto .b
  237. &str    setc    &substr(&str,2,999)
  238. &deref    seta    &deref+1
  239.     goto    .a
  240. .b    if    &substr(&str,1,1)='<' then
  241. ayisbyte    set    1
  242. &str    setc    &substr(&str,2,999)
  243.     endif
  244.     lda    &str
  245.     if    &deref>0 goto .c
  246.     if    ayisbyte=1 goto .d
  247. .c    ldy    &str+1
  248. .d    if    &deref>0 then
  249.     jsr    deref
  250. &deref    seta    &deref-1
  251.     goto    .d
  252.     endif
  253.     mexit
  254. .imm
  255. &str    setc    &substr(&str,2,999)
  256.     if    &substr(&str,1,1)='<' then
  257. ayisbyte    set    1
  258. &str    setc    &substr(&str,2,999)
  259.     endif
  260.     lda    #<&str
  261.     if    ayisbyte=0 then
  262.     ldy    #>&str
  263.     endif
  264.     MEND
  265.  
  266.  
  267. *****************************************************************
  268. *****************************************************************
  269. *****************************************************************
  270.  
  271.  
  272.     MACRO
  273. &lab    _int    &op
  274. &lab    aycorm    &op
  275.     if    ayisbyte=1 then
  276.     ldy    #0
  277.     endif
  278.     MEND
  279.  
  280.  
  281. *****************************************************************
  282.  
  283.  
  284.     MACRO
  285. &lab    _ptr    &op
  286. &lab    aycorm    &op
  287.     if    ayisbyte=1 then
  288.     ldy    #0
  289.     endif
  290.     MEND
  291.  
  292.  
  293. *****************************************************************
  294.  
  295.  
  296.     MACRO
  297. &lab    _byte    &op
  298. &lab    acorm    &op
  299.     MEND
  300.  
  301.  
  302. *****************************************************************
  303. *****************************************************************
  304. *****************************************************************
  305.  
  306.  
  307. * This macro initializes everything necessary in the runtime and runtime
  308. * macros.  It initializes global macro variables and resets everything
  309. * in the runtime so the application can resume if the user presses a reset.
  310.     MACRO
  311. &lab    _rtreset
  312. &lab    jsr    rtreset
  313.     MEND
  314.  
  315.  
  316. ***************************************
  317.  
  318.  
  319. * This macro is used to turn on the hi-bit for characters that are sent to rtcout.
  320.     MACRO
  321. &lab    _hibitchrs
  322. &lab    jsr    hibitchrs
  323.     MEND
  324.  
  325.  
  326. ***************************************
  327.  
  328.  
  329. * This macro is used to turn off the hi-bit for characters that are sent to rtcout.
  330.     MACRO
  331. &lab    _lowbitchrs
  332. &lab    jsr    lowbitchrs
  333.     MEND
  334.  
  335.  
  336. ***************************************
  337.  
  338.  
  339. * This macro is used to make sure that characters sent to rtcout are used as-is.  There
  340. * will be no modification of the hi-bit.
  341.     MACRO
  342. &lab    _regchrs
  343. &lab    jsr    regchrs
  344.     MEND
  345.  
  346.  
  347. ***************************************
  348.  
  349.  
  350. * This macro prints a character.  This character is either already in the acc
  351. * (no operand), or what is described by the operand.  The operand can either
  352. * be an absolute or a value in memory.
  353. * (acorm means load Acc with a Constant OR Memory value).
  354.     MACRO
  355. &lab    _rtcout    &op
  356. &lab
  357.     if    &op='' goto .jsr
  358.     acorm    &op
  359. .jsr    jsr    rtcout
  360.     MEND
  361.  
  362.  
  363. ***************************************
  364.  
  365.  
  366. * This macro prints ascii data following the _write macro.  The write routine
  367. * works by using the return address as a pointer to the ascii data.  The ascii
  368. * data is terminated with a 0 (C-string style).  When the write routine
  369. * encounters a 0, it sets the return address so the when an rts is executed,
  370. * it returns to the code following the 0 terminator.  As many parameters as
  371. * are desired can be passed to this routine.  If the ascii data is more than
  372. * 1 line, end it with a comma,backslash to indicate line continuation.
  373.     MACRO
  374. &lab    _write
  375. &lab    
  376.     if    &syslist[1]='' then
  377.     aerror    '_write:  must have at least one parameter'
  378.     mexit
  379.     endif
  380.     jsr    write
  381.     lcla    &i,&n
  382. &i    seta    1
  383. &n    seta    &nbr(&syslist)
  384. .a    dc.b    &syslist[&i]
  385. &i    seta    &i+1
  386.     if    &i<=&n goto .a
  387.     dc.b    0
  388.     MEND
  389.  
  390.  
  391. ***************************************
  392.  
  393.  
  394. * This macro prints a carriage return.
  395.     MACRO
  396. &lab    _writecr
  397. &lab    jsr    writecr
  398.     MEND
  399.  
  400.  
  401. ***************************************
  402.  
  403.  
  404. * This macro prints a c string pointed to by the operand.
  405.     MACRO
  406. &lab    _wrcstr    &op
  407. &lab    aycorm    &op
  408.     if    ayisbyte=1 then
  409.     ldy    #0
  410.     endif
  411.     jsr    wrcstr
  412.     MEND
  413.  
  414.  
  415. ***************************************
  416. ***************************************
  417. ***************************************
  418.  
  419.  
  420. * This macro sets signed mode.  Printing decimal numbers is affected by this.
  421.     MACRO
  422. &lab    _signed
  423. &lab    jsr    signed
  424.     MEND
  425.  
  426.  
  427. ***************************************
  428.  
  429.  
  430. * This macro sets unsigned mode.  Printing decimal numbers is affected by this.
  431.     MACRO
  432. &lab    _unsigned
  433. &lab    jsr    unsigned
  434.     MEND
  435.  
  436.  
  437. ***************************************
  438.  
  439.  
  440. * This macro does a two's compliment on the variable.
  441.     MACRO
  442. &lab    _chngsgn
  443. &lab    jsr    chngsgn
  444.     MEND
  445.  
  446.  
  447. ***************************************
  448.  
  449.  
  450. * This macro prints a 1-byte decimal value.  This value is either already in
  451. * the acc (no operand), or what is described by the operand.  The operand can
  452. * either be an absolute or a value in memory.
  453.     MACRO
  454. &lab    _decoutl    &op
  455. &lab    
  456.     if    &op='' goto .jsr
  457.     acorm    &op
  458. .jsr    jsr    decoutl
  459.     MEND
  460.  
  461.  
  462. ***************************************
  463.  
  464.  
  465. * This macro prints a 2-byte decimal value.  This value is stored in a
  466. * variable.  The variable number is either already in the xreg (no operand),
  467. * or is determined by the operand.
  468.     MACRO
  469. &lab    _vdecout    &op
  470. &lab    
  471.     if    &op='' goto .jsr
  472.     ldx    #<&op
  473. .jsr    jsr    vdecout
  474.     MEND
  475.  
  476.  
  477. ***************************************
  478.  
  479.  
  480. * This macro prints a 1- or 2-byte decimal value.  This value is either already
  481. * in the acc,y (no operand), or what is described by the operand.  The operand
  482. * can either be an absolute or a value in memory.
  483.     MACRO
  484. &lab    _decout    &op
  485. &lab    
  486.     if    &op='' goto .jsr
  487.     aycorm    &op
  488.     if    ayisbyte=1 then
  489.     jsr    decoutl
  490.     mexit
  491.     endif
  492. .jsr    jsr    decout
  493.     MEND
  494.  
  495.  
  496. ***************************************
  497.  
  498.  
  499. * This macro sets pad mode for hex.  The value is either already in the acc
  500. * (no operand), or what is described by the operand.  The operand can either
  501. * be an absolute or a value in memory.  Printing hex numbers is affected by
  502. * this.
  503.     MACRO
  504. &lab    _hexpad    &op
  505. &lab    
  506.     if    &op='' goto .jsr
  507.     acorm    &op
  508. .jsr    jsr    hexpad
  509.     MEND
  510.  
  511.  
  512. ***************************************
  513.  
  514.  
  515. * This macro sets no pad mode for hex.  Printing hex numbers is affected by
  516. * this.
  517.     MACRO
  518. &lab    _hexnopad
  519. &lab    jsr    hexnopad
  520.     MEND
  521.  
  522.  
  523. ***************************************
  524.  
  525.  
  526. * This macro prints a 1-byte hex value.  This value is either already in the
  527. * acc (no operand), or what is described by the operand.  The operand can
  528. * either be an absolute or a value in memory.
  529.     MACRO
  530. &lab    _hexoutl    &op
  531. &lab    
  532.     if    &op='' goto .jsr
  533.     acorm    &op
  534. .jsr    jsr    hexoutl
  535.     MEND
  536.  
  537.  
  538. ***************************************
  539.  
  540.  
  541. * This macro prints a 2-byte hex value.  This value is stored in a variable.
  542. * The variable number is either already in the xreg (no operand), or is
  543. * determined by the operand.
  544.     MACRO
  545. &lab    _vhexout    &op
  546. &lab    
  547.     if    &op='' goto .jsr
  548.     ldx    #<&op
  549. .jsr    jsr    vhexout
  550.     MEND
  551.  
  552.  
  553. ***************************************
  554.  
  555.  
  556. * This macro prints a 1- or 2-byte hex value.  This value is either already in
  557. * the acc,y (no operand), or what is described by the operand.  The operand can
  558. * either be an absolute or a value in memory.
  559.     MACRO
  560. &lab    _hexout    &op
  561. &lab    
  562.     if    &op='' goto .jsr
  563.     aycorm    &op
  564.     if    ayisbyte=1 then
  565.     ldy    #0
  566.     endif
  567. .jsr    jsr    hexout
  568.     MEND
  569.  
  570.  
  571. ***************************************
  572.  
  573.  
  574. * This macro adds a variable to the destination variable.  If there is no
  575. * op1, then the destination variable number is assumed to be in the xreg.
  576. * If there is no op2, then the source variable number is assumed to be in
  577. * the yreg.
  578.     MACRO
  579. &lab    _addvar    &op1,&op2
  580. &lab
  581.     if    &op1='' goto .a
  582.     ldx    #<&op1
  583. .a    if    &op2='' goto .jsr
  584.     ldy    #<&op2
  585. .jsr    jsr    addvar
  586.     MEND
  587.  
  588.  
  589. ***************************************
  590.  
  591.  
  592. * This macro adds a 1-byte value to the destination variable.  If there is
  593. * no op1, then the destination variable number is assumed to be in the xreg.
  594. * If there is no op2, then the value is assumed to be in the acc.
  595.     MACRO
  596. &lab    _addl    &op1,&op2
  597. &lab
  598.     if    &op1='' goto .a
  599.     ldx    #<&op1
  600. .a    if    &op2='' goto .jsr
  601.     acorm    &op2
  602. .jsr    jsr    addconl
  603.     MEND
  604.  
  605.  
  606. ***************************************
  607.  
  608.  
  609. * This macro adds a 2-byte value to the destination variable.  If there is
  610. * no op1, then the destination variable number is assumed to be in the xreg.
  611. * If there is no op2, then the value is assumed to be in acc,y.
  612.     MACRO
  613. &lab    _add    &op1,&op2
  614. &lab
  615.     if    &op1='' goto .a
  616.     ldx    #<&op1
  617. .a    if    &op2='' goto .jsr
  618.     aycorm    &op2
  619.     if    ayisbyte=1 then
  620.     jsr    addconl
  621.     mexit
  622.     endif
  623. .jsr    jsr    addcon
  624.     MEND
  625.  
  626.  
  627. ***************************************
  628.  
  629.  
  630. * This macro subtracts a variable from the destination variable.  If there is
  631. * no op1, then the destination variable number is assumed to be in the xreg.
  632. * If there is no op2, then the source variable number is assumed to be in
  633. * the yreg.
  634.     MACRO
  635. &lab    _subvar    &op1,&op2
  636. &lab
  637.     if    &op1='' goto .a
  638.     ldx    #<&op1
  639. .a    if    &op2='' goto .jsr
  640.     ldy    #<&op2
  641. .jsr    jsr    subvar
  642.     MEND
  643.  
  644.  
  645. ***************************************
  646.  
  647.  
  648. * This macro subtracts a 1-byte value from the destination variable.  If there
  649. * is no op1, then the destination variable number is assumed to be in the xreg.
  650. * If there is no op2, then the value is assumed to be in the acc.
  651.     MACRO
  652. &lab    _subl    &op1,&op2
  653. &lab
  654.     if    &op1='' goto .a
  655.     ldx    #<&op1
  656. .a    if    &op2='' goto .jsr
  657.     acorm    &op2
  658. .jsr    jsr    subconl
  659.     MEND
  660.  
  661.  
  662. ***************************************
  663.  
  664.  
  665. * This macro subtracts a 2-byte value from the destination variable.  If there
  666. * is no op1, then the destination variable number is assumed to be in the xreg.
  667. * If there is no op2, then the value is assumed to be in acc,y.
  668.     MACRO
  669. &lab    _sub    &op1,&op2
  670. &lab
  671.     if    &op1='' goto .a
  672.     ldx    #<&op1
  673. .a    if    &op2='' goto .jsr
  674.     aycorm    &op2
  675.     if    ayisbyte=1 then
  676.     jsr    subconl
  677.     mexit
  678.     endif
  679. .jsr    jsr    subcon
  680.     MEND
  681.  
  682.  
  683. ***************************************
  684.  
  685.  
  686. * This macro multiplies the destination variable by a variable.  If there is
  687. * no op1, then the destination variable number is assumed to be in the xreg.
  688. * If there is no op2, then the source variable number is assumed to be in
  689. * the yreg.
  690.     MACRO
  691. &lab    _mulvar    &op1,&op2
  692. &lab
  693.     if    &op1='' goto .a
  694.     ldx    #<&op1
  695. .a    if    &op2='' goto .jsr
  696.     ldy    #<&op2
  697. .jsr    jsr    mulvar
  698.     MEND
  699.  
  700.  
  701. ***************************************
  702.  
  703.  
  704. * This macro multiplies the destination variable by a 1-byte value.  If there
  705. * is no op1, then the destination variable number is assumed to be in the xreg.
  706. * If there is no op2, then the value is assumed to be in the acc.
  707.     MACRO
  708. &lab    _mull    &op1,&op2
  709. &lab
  710.     if    &op1='' goto .a
  711.     ldx    #<&op1
  712. .a    if    &op2='' goto .jsr
  713.     acorm    &op2
  714. .jsr    jsr    mulconl
  715.     MEND
  716.  
  717.  
  718. ***************************************
  719.  
  720.  
  721. * This macro multiplies the destination variable by a 2-byte value.  If there
  722. * is no op1, then the destination variable number is assumed to be in the xreg.
  723. * If there is no op2, then the value is assumed to be in acc,y.
  724.     MACRO
  725. &lab    _mul    &op1,&op2
  726. &lab
  727.     if    &op1='' goto .a
  728.     ldx    #<&op1
  729. .a    if    &op2='' goto .jsr
  730.     aycorm    &op2
  731.     if    ayisbyte=1 then
  732.     jsr    mulconl
  733.     mexit
  734.     endif
  735. .jsr    jsr    mulcon
  736.     MEND
  737.  
  738.  
  739. ***************************************
  740.  
  741.  
  742. * This macro divides the destination variable by a variable.  If there is
  743. * no op1, then the destination variable number is assumed to be in the xreg.
  744. * If there is no op2, then the source variable number is assumed to be in
  745. * the yreg.  The remainder from the divide is in the acc,y.
  746.     MACRO
  747. &lab    _divvar    &op1,&op2
  748. &lab
  749.     if    &op1='' goto .a
  750.     ldx    #<&op1
  751. .a    if    &op2='' goto .jsr
  752.     ldy    #<&op2
  753. .jsr    jsr    divvar
  754.     MEND
  755.  
  756.  
  757. ***************************************
  758.  
  759.  
  760. * This macro divides the destination variable by a 1-byte value.  If there
  761. * is no op1, then the destination variable number is assumed to be in the xreg.
  762. * If there is no op2, then the value is assumed to be in the acc.  The
  763. * remainder from the divide is in the acc,y.
  764.     MACRO
  765. &lab    _divl    &op1,&op2
  766. &lab
  767.     if    &op1='' goto .a
  768.     ldx    #<&op1
  769. .a    if    &op2='' goto .jsr
  770.     acorm    &op2
  771. .jsr    jsr    divconl
  772.     MEND
  773.  
  774.  
  775. ***************************************
  776.  
  777.  
  778. * This macro divides the destination variable by a 2-byte value.  If there
  779. * is no op1, then the destination variable number is assumed to be in the xreg.
  780. * If there is no op2, then the value is assumed to be in acc,y.  The remainder
  781. * from the divide is in the acc,y.
  782.     MACRO
  783. &lab    _div    &op1,&op2
  784. &lab
  785.     if    &op1='' goto .a
  786.     ldx    #<&op1
  787. .a    if    &op2='' goto .jsr
  788.     aycorm    &op2
  789.     if    ayisbyte=1 then
  790.     jsr    divconl
  791.     mexit
  792.     endif
  793. .jsr    jsr    divcon
  794.     MEND
  795.  
  796.  
  797. ***************************************
  798.  
  799.  
  800. * This macro sets the current variable.  The current variable is defined by
  801. * a number in the xreg.  All runtime functions preserve the xreg, so multiple
  802. * operations can be done to the same variable without having to reload the xreg
  803. * with the variable number.
  804.     MACRO
  805. &lab    _var    &op
  806. &lab    ldx    #<&op
  807.     MEND
  808.  
  809.  
  810. ***************************************
  811.  
  812. * This macro uses a variable as a pointer and sets that variable to the value to where
  813. * that pointer currently points.  The macro preserves all registers.
  814. * The c equivalent would be (using longs instead if ints):
  815. *
  816. *    long    *ptrvar;
  817. *
  818. *    ptrvar = (long *)*ptrvar;
  819.     MACRO
  820. &lab    _vderef    &op
  821. &lab    
  822.     if    &op='' goto .jsr
  823.     ldx    #<&op
  824. .jsr    jsr    vderef
  825.     MEND
  826.  
  827.  
  828. ***************************************
  829.  
  830.  
  831. * This macro sets a variable to 0.  If there is no op1, then the destination
  832. * variable number is assumed to be in the xreg.
  833.     MACRO
  834. &lab    _set0    &op
  835. &lab    
  836.     if    &op='' goto .jsr
  837.     ldx    #<&op
  838. .jsr    jsr    setzero
  839.     MEND
  840.  
  841.  
  842. ***************************************
  843.  
  844.  
  845. * This macro sets a variable to another variable.  If there is no op1, then the
  846. * destination variable number is assumed to be in the xreg.  If there is no
  847. * op2, then the source variable number is assumed to be in the yreg.
  848.     MACRO
  849. &lab    _varcpy    &op1,&op2
  850. &lab    
  851.     if    &op1='' goto .a
  852.     ldx    #<&op1
  853. .a    if    &op2='' goto .jsr
  854.     ldy    #<&op2
  855. .jsr    jsr    seteq
  856.     MEND
  857.  
  858.  
  859. ***************************************
  860.  
  861.  
  862. * This macro sets a variable to a 1-byte value.  If there is no op1, then the
  863. * destination variable number is assumed to be in the xreg.  If there is no
  864. * op2, then the value is assumed to be in the acc.
  865.     MACRO
  866. &lab    _setl    &op1,&op2
  867. &lab    
  868.     if    &op1='' goto .a
  869.     ldx    #<&op1
  870. .a    if    &op2='' goto .jsr
  871.     acorm    &op2
  872. .jsr    jsr    setconl
  873.     MEND
  874.  
  875.  
  876. ***************************************
  877.  
  878.  
  879. * This macro sets a variable to a 2-byte value.  If there is no op1, then the
  880. * destination variable number is assumed to be in the xreg.  If there is no
  881. * op2, then the value is assumed to be in acc,y.
  882.     MACRO
  883. &lab    _set    &op1,&op2
  884. &lab    
  885.     if    &op1='' goto .a
  886.     ldx    #<&op1
  887. .a    if    &op2='' goto .jsr
  888.     aycorm    &op2
  889.     if    ayisbyte=1 then
  890.     jsr    setconl
  891.     mexit
  892.     endif
  893. .jsr    jsr    setcon
  894.     MEND
  895.  
  896.  
  897. ***************************************
  898.  
  899.  
  900. * This macro is used to set a bunch of variables to constant values.
  901. * There must be a non-zero even number of parameters.  The odd parameters
  902. * are the variables, and the even parameters are the constant values for
  903. * the preceeding parameter.  The setvars routine uses the return address
  904. * as a pointer to the data (just like the write routine).  It simply
  905. * sets the designated variable to the designated constant until it
  906. * encounters a 255 as a variable value.  A 255 is reserved for this
  907. * purpose.  This macro places a 255 at the end of the data list
  908. * automatically.
  909.     MACRO
  910. &lab    _setvars
  911. &lab    
  912.     if    &syslist[2]='' then
  913.     aerror    '_setvars:  must have at least two parameters'
  914.     mexit
  915.     endif
  916.     jsr    setvars
  917.     lcla    &i,&j,&n
  918. &i    seta    1
  919. &j    seta    2
  920. &n    seta    &nbr(&syslist)
  921. .a    if    &syslist[&j]='' then
  922.     aerror    '_setvars:  must have even number of parameters'
  923.     mexit
  924.     endif
  925.     dc.b    &syslist[&i]
  926.     if    &substr(&syslist[&j],1,1)<>'#' then
  927.     aerror    '_setvars:  variables can only be set to constants -- missing #'
  928.     mexit
  929.     endif
  930.     dc.w    &substr(&syslist[&j],2,999)
  931. &i    seta    &i+2
  932. &j    seta    &j+2
  933.     if    &i<=&n goto .a
  934.     dc.b    255
  935.     MEND
  936.  
  937.  
  938. ***************************************
  939.  
  940.  
  941. * This macro swaps the two variables if the xreg variable is bigger than the
  942. * yreg variable.  If there is no op1, then the destination variable number is
  943. * assumed to be in the xreg.  If there is no op2, then the source variable
  944. * number is assumed to be in the yreg.
  945.     MACRO
  946. &lab    _minswap    &op1,&op2    
  947. &lab    
  948.     if    &op1='' goto .a
  949.     ldx    #<&op1
  950. .a    if    &op2='' goto .jsr
  951.     ldy    #<&op2
  952. .jsr    jsr    xlty
  953.     MEND
  954.  
  955.  
  956. ***************************************
  957.  
  958.  
  959. * This macro swaps the two variables if the xreg variable is smaller than the
  960. * yreg variable.  If there is no op1, then the destination variable number is
  961. * assumed to be in the xreg.  If there is no op2, then the source variable
  962. * number is assumed to be in the yreg.
  963.     MACRO
  964. &lab    _maxswap    &op1,&op2    
  965. &lab    
  966.     if    &op1='' goto .a
  967.     ldx    #<&op1
  968. .a    if    &op2='' goto .jsr
  969.     ldy    #<&op2
  970. .jsr    jsr    xgty
  971.     MEND
  972.  
  973.  
  974. ***************************************
  975.  
  976.  
  977. * This macro does a signed compare of two variables.  The equal status is true
  978. * if the variables are equal.  If the xreg variable is greater or equal, then
  979. * the carry is set.  If the xreg variable is smaller, then the carry is clear.
  980. * If there is no op1, then the variable number is assumed to be in the xreg.
  981. * If there is no op2, then the variable number is assumed to be in the yreg.
  982.     MACRO
  983. &lab    _vsgncmp    &op1,&op2    
  984. &lab
  985.     if    &op1='' goto .a
  986.     ldx    #<&op1
  987. .a    if    &op2='' goto .jsr
  988.     ldy    #<&op2
  989. .jsr    jsr    vifsgneq
  990.     MEND
  991.  
  992.  
  993. ***************************************
  994.  
  995.  
  996. * This macro does an unsigned compare of two variables.  The equal status is
  997. * true if the variables are equal.  If the xreg variable is greater or equal,
  998. * then the carry is set.  If the xreg variable is smaller, then the carry is
  999. * clear.  If there is no op1, then the variable number is assumed to be in the
  1000. * xreg.  If there is no op2, then the variable number is assumed to be in the
  1001. * yreg.
  1002.     MACRO
  1003. &lab    _vcmp    &op1,&op2    
  1004. &lab
  1005.     if    &op1='' goto .a
  1006.     ldx    #<&op1
  1007. .a    if    &op2='' goto .jsr
  1008.     ldy    #<&op2
  1009. .jsr    jsr    vifequal
  1010.     MEND
  1011.  
  1012.  
  1013. ***************************************
  1014.  
  1015.  
  1016. * This macro works the same as _vsgncmp, except that it compares a variable
  1017. * against a constant or value from memory at a specified location.
  1018.     MACRO
  1019. &lab    _sgncmp    &op1,&op2    
  1020. &lab
  1021.     if    &op1='' goto .a
  1022.     ldx    #<&op1
  1023. .a    if    &op2='' goto .jsr
  1024.     aycorm    &op2
  1025.     if    ayisbyte=1 then
  1026.     ldy    #0
  1027.     endif
  1028. .jsr    jsr    ifsgneq
  1029.     MEND
  1030.  
  1031.  
  1032. ***************************************
  1033.  
  1034.  
  1035. * This macro works the same as _vcmp, except that it compares a variable
  1036. * against a constant or value from memory at a specified location.
  1037.     MACRO
  1038. &lab    _cmp    &op1,&op2    
  1039. &lab
  1040.     if    &op1='' goto .a
  1041.     ldx    #<&op1
  1042. .a    if    &op2='' goto .jsr
  1043.     aycorm    &op2
  1044.     if    ayisbyte=1 then
  1045.     ldy    #0
  1046.     endif
  1047. .jsr    jsr    ifequal
  1048.     MEND
  1049.  
  1050.  
  1051. ***************************************
  1052. ***************************************
  1053. ***************************************
  1054.  
  1055.  
  1056. * This macro is used to seed the random number generator.  If there is
  1057. * no op1, then the random seed is assumed to be in the acc,y.
  1058.     MACRO
  1059. &lab    _rndseed    &op
  1060. &lab    
  1061.     if    &op='' goto .jsr
  1062.     aycorm    &op
  1063.     if    ayisbyte=1 then
  1064.     ldy    #0
  1065.     endif
  1066. .jsr    jsr    seedrandom
  1067.     MEND
  1068.  
  1069.  
  1070. ***************************************
  1071.  
  1072.  
  1073. * This macro is used to return a random number from 0 to op - 1.  If there is
  1074. * no op1, then the random number limit is assumed to be in the acc,y.
  1075.     MACRO
  1076. &lab    _random    &op
  1077. &lab    
  1078.     if    &op='' goto .jsr
  1079.     aycorm    &op
  1080.     if    ayisbyte=1 then
  1081.     ldy    #0
  1082.     endif
  1083. .jsr    jsr    calcrandom
  1084.     MEND
  1085.  
  1086.  
  1087. ***************************************
  1088. ***************************************
  1089. ***************************************
  1090.  
  1091.  
  1092. * This macro takes the value of a string and returns it in the acc,y.
  1093. * If there is no op1, then the string number is assumed to be in the xreg.
  1094.     MACRO
  1095. &lab    _strval    &op
  1096. &lab
  1097.     if    &op='' goto .jsr
  1098.     ldx    #<&op
  1099. .jsr    jsr    strval
  1100.     MEND
  1101.  
  1102.  
  1103. ***************************************
  1104.  
  1105.  
  1106. * This macro takes the value of op1 string starting at op2 character and
  1107. * returns it in the acc,y.  If there is no op1, then the string number is
  1108. * assumed to be in the xreg.  If there is no op2, then the character number
  1109. * is assumed to be in the yreg.
  1110.     MACRO
  1111. &lab    _midstrval &op1,&op2
  1112. &lab
  1113.     if    &op1='' goto .a
  1114.     ldx    #<&op1
  1115. .a    if    &op2='' goto .jsr
  1116.     ycorm    &op2
  1117. .jsr    jsr    midstrval
  1118.     MEND
  1119.  
  1120.  
  1121. ***************************************
  1122.  
  1123.  
  1124. * This macro prints the entire string.  If there is no op1, then the string
  1125. * number is assumed to be in the xreg.
  1126.     MACRO
  1127. &lab    _prstr    &op
  1128. &lab    
  1129.     if    &op='' goto .jsr
  1130.     ldx    #<&op
  1131. .jsr    jsr    prstr
  1132.     MEND
  1133.  
  1134.  
  1135. ***************************************
  1136.  
  1137.  
  1138. * This macro prints op1 string starting at the first character for op2
  1139. * characters.  If there is no op1, then the string number is assumed to be
  1140. * in the xreg.  If there is no op2, then the number of characters is assumed
  1141. * to be in the acc.
  1142.     MACRO
  1143. &lab    _prleftstr &op1,&op2
  1144. &lab
  1145.     if    &op1='' goto .a
  1146.     ldx    #<&op1
  1147. .a    if    &op2='' goto .jsr
  1148.     acorm    &op2
  1149. .jsr    jsr    prleftstr
  1150.     MEND
  1151.  
  1152.  
  1153. ***************************************
  1154.  
  1155.  
  1156. * This macro prints op1 string starting at the op2 character for op3
  1157. * characters.  If there is no op1, then the string number is assumed to be
  1158. * in the xreg.  If there is no op2, then the character number is assumed to
  1159. * be in the yreg.  If there is no op3, then the number of characters is
  1160. * assumed to be in the acc.
  1161.     MACRO
  1162. &lab    _prmidstr &op1,&op2,&op3
  1163. &lab
  1164.     if    &op1='' goto .a
  1165.     ldx    #<&op1
  1166. .a    if    &op2='' goto .b
  1167.     ycorm    &op2
  1168. .b    if    &op3='' goto .jsr
  1169.     acorm    &op3
  1170. .jsr    jsr    prmidstr
  1171.     MEND
  1172.  
  1173.  
  1174. ***************************************
  1175.  
  1176.  
  1177. * This macro copies op3 characters from op2 string to op1 string.  If there
  1178. * is no op1, then the destination string number is assumed to be in the xreg.
  1179. * If there is no op2, then the source string number is assumed to be in the
  1180. * yreg.  If there is no op3, then the number of characters is assumed to be
  1181. * in the acc.
  1182.     MACRO
  1183. &lab    _leftstrcpy &op1,&op2,&op3
  1184. &lab    
  1185.     if    &op1='' goto .a
  1186.     ldx    #<&op1
  1187. .a    if    &op2='' goto .b
  1188.     ldy    #<&op2
  1189. .b    if    &op3='' goto .jsr
  1190.     acorm    &op3
  1191. .jsr    jsr    leftstrcpy
  1192.     MEND
  1193.  
  1194.  
  1195. ***************************************
  1196.  
  1197.  
  1198. * This macro copies op2 string to op1 string.  If there is no op1, then the
  1199. * destination string number is assumed to be in the xreg.  If there is no op2,
  1200. * then the source string number is assumed to be in the yreg.
  1201.     MACRO
  1202. &lab    _strcpy &op1,&op2
  1203. &lab    
  1204.     if    &op1='' goto .a
  1205.     ldx    #<&op1
  1206. .a    if    &op2='' goto .jsr
  1207.     ldy    #<&op2
  1208. .jsr    jsr    strcpy
  1209.     MEND
  1210.  
  1211.  
  1212. ***************************************
  1213.  
  1214.  
  1215. * This macro copies op4 characters, starting at op3 character from op2 string
  1216. * to op1 string.  If there is no op1, then the destination string number is
  1217. * assumed to be in the xreg.  If there is no op2, then the source string number
  1218. * is assumed to be in the yreg.  If there is no op3, then the character number
  1219. * is assumed to be in the acc.  If there is no op4, then all characters to the
  1220. * end of the source string will be copied to the destination string.  The op4
  1221. * case is the only case where the assumed value is a particular value (#255),
  1222. * instead of what is in a register.  This is the case because there are only
  1223. * three registers.
  1224.     MACRO
  1225. &lab    _midstrcpy &op1,&op2,&op3,&op4
  1226. &lab
  1227.     if    &op4='' goto .b
  1228.     if    &op3<>'' goto .a
  1229.     pha
  1230. .a
  1231.     acorm    &op4
  1232.     sta    numtocopy
  1233.     if    &op3<>'' goto .b
  1234.     pla
  1235. .b    if    &op1='' goto .c
  1236.     ldx    #<&op1
  1237. .c    if    &op2='' goto .d
  1238.     ldy    #<&op2
  1239. .d    if    &op3='' goto .jsr
  1240.     acorm    &op3
  1241. .jsr    jsr    midstrcpy
  1242.     MEND
  1243.  
  1244.  
  1245. ***************************************
  1246.  
  1247.  
  1248. * This macro concatenates op3 characters of op2 string onto op1 string.  If
  1249. * there is no op1, then the destination string number is assumed to be in the
  1250. * xreg.  If there is no op2, then the source string number is assumed to be in
  1251. * the yreg.  If there is no op3, then the number of characters is assumed to
  1252. * be in the acc.
  1253.     MACRO
  1254. &lab    _leftstrcat &op1,&op2,&op3
  1255. &lab    
  1256.     if    &op1='' goto .a
  1257.     ldx    #<&op1
  1258. .a    if    &op2='' goto .b
  1259.     ldy    #<&op2
  1260. .b    if    &op3='' goto .jsr
  1261.     acorm    &op3
  1262. .jsr    jsr    leftstrcat
  1263.     MEND
  1264.  
  1265.  
  1266. ***************************************
  1267.  
  1268.  
  1269. * This macro concatenates op2 string onto op1 string.  If there is no op1,
  1270. * then the destination string number is assumed to be in the xreg.  If there
  1271. * is no op2, then the source string number is assumed to be in the yreg.
  1272.     MACRO
  1273. &lab    _strcat &op1,&op2
  1274. &lab    
  1275.     if    &op1='' goto .a
  1276.     ldx    #<&op1
  1277. .a    if    &op2='' goto .jsr
  1278.     ldy    #<&op2
  1279. .jsr    jsr    strcat
  1280.     MEND
  1281.  
  1282.  
  1283. ***************************************
  1284.  
  1285.  
  1286. * This macro concatenates op4 characters starting at op3 character from op2
  1287. * string onto op1 string.  If there is no op1, then the destination string
  1288. * number is assumed to be in the xreg.  If there is no op2, then the source
  1289. * string number is assumed to be in the yreg.  If there is no op3, then the
  1290. * character number is assumed to be in the acc.  If there is no op4, then all
  1291. * characters to the end of the source string will be concatenated to the
  1292. * destination string.  The op4 case is the only case where the assumed value
  1293. * is a particular value (#255), instead of what is in a register.  This is
  1294. * the case because there are only three registers.
  1295.     MACRO
  1296. &lab    _midstrcat &op1,&op2,&op3,&op4
  1297. &lab
  1298.     if    &op4='' goto .b
  1299.     if    &op3<>'' goto .a
  1300.     pha
  1301. .a
  1302.     acorm    &op4
  1303.     sta    numtocopy
  1304.     if    &op3<>'' goto .b
  1305.     pla
  1306. .b    if    &op1='' goto .c
  1307.     ldx    #<&op1
  1308. .c    if    &op2='' goto .d
  1309.     ldy    #<&op2
  1310. .d    if    &op3='' goto .jsr
  1311.     acorm    &op3
  1312. .jsr    jsr    midstrcat
  1313.     MEND
  1314.  
  1315.  
  1316. ***************************************
  1317.  
  1318.  
  1319. * This macro is used to take some literal string data and place it into
  1320. * a string.  It works very much like the write routine, except that it
  1321. * copies the characters into a string instead of printing them.  Operand
  1322. * 1 is the string variable, if there is one designated.  If there is not
  1323. * one designated, then the x-reg is assumed to already hold it.  There
  1324. * then must be a second parameter.  This parameter would be string data.
  1325. * There may be other parameters, which would also hold string data.
  1326. * When all data parameters are used by this macro, the macro then places
  1327. * a 0 terminator to indicate the end of the literal data.
  1328.     MACRO
  1329. &lab    _litstr
  1330. &lab    
  1331.     if    &syslist[2]='' then
  1332.     aerror    '_litstr:  must have a second parameter'
  1333.     mexit
  1334.     endif
  1335.     if    &syslist[1]='' goto .jsr
  1336.     ldx    #<&syslist[1]
  1337. .jsr    jsr    litstr
  1338.     lcla    &i,&n
  1339. &i    seta    2
  1340. &n    seta    &nbr(&syslist)
  1341. .a    dc.b    &syslist[&i]
  1342. &i    seta    &i+1
  1343.     if    &i<=&n goto .a
  1344.     dc.b    0
  1345.     MEND
  1346.  
  1347.  
  1348. ***************************************
  1349.  
  1350.  
  1351. * This macro returns the op2th character of op1 string.  If there is no op1,
  1352. * then the destination string number is assumed to be in the xreg.  If there
  1353. * is no op2, then the character number is assumed to be in the acc.
  1354.     MACRO
  1355. &lab    _strchr &op1,&op2
  1356. &lab    
  1357.     if    &op1='' goto .a
  1358.     ldx    #<&op1
  1359. .a    if    &op2='' goto .jsr
  1360.     acorm    &op2
  1361. .jsr    jsr    strchr
  1362.     MEND
  1363.  
  1364.  
  1365. ***************************************
  1366.  
  1367.  
  1368. * This macro returns the physical location of op1 string in memory.  The
  1369. * string location is returned in acc,y.If there is no op1, then the
  1370. * destination string number is assumed to be in the xreg.
  1371.     MACRO
  1372. &lab    _strloc &op1
  1373. &lab    
  1374.     if    &op1='' goto .jsr
  1375.     ldx    #<&op1
  1376. .jsr    jsr    strloc
  1377.     MEND
  1378.  
  1379.  
  1380. ***************************************
  1381.  
  1382.  
  1383.     MACRO
  1384. &lab    _cstr
  1385. &lab    
  1386.     if    &syslist[1]='' then
  1387.     aerror    '_write:  must have at least one parameter'
  1388.     mexit
  1389.     endif
  1390.     lcla    &i,&n
  1391. &i    seta    1
  1392. &n    seta    &nbr(&syslist)
  1393. .a    dc.b    &syslist[&i]
  1394. &i    seta    &i+1
  1395.     if    &i<=&n goto .a
  1396.     dc.b    0
  1397.     MEND
  1398.  
  1399.  
  1400. ***************************************
  1401. ***************************************
  1402. ***************************************
  1403.  
  1404.  
  1405. * This macro sets the read data pointer.  If there is no op, then the address
  1406. * for reading data is assumed to be in the acc,y.
  1407.     MACRO
  1408. &lab    _restore    &op
  1409. &lab
  1410.     if    &op='' goto .jsr
  1411.     aycorm    &op
  1412.     if    ayisbyte=1 then
  1413.     ldy    #0
  1414.     endif
  1415. .jsr    jsr    restore
  1416.     MEND
  1417.  
  1418.  
  1419. ***************************************
  1420.  
  1421.  
  1422. * This macro reads an int from the current data pointer and advances the
  1423. * pointer by two bytes.  If there is no op1, then the destination variable
  1424. * number is assumed to be in the xreg.
  1425.     MACRO
  1426. &lab    _readint    &op
  1427. &lab    
  1428.     if    &op='' goto .jsr
  1429.     ldx    #<&op
  1430. .jsr    jsr    readint
  1431.     MEND
  1432.  
  1433.  
  1434. ***************************************
  1435.  
  1436.  
  1437. * This macro reads string data into the designated string until the
  1438. * end-of-string character is encountered.  The data pointer is then set to
  1439. * point after this end-of-string character.  If there is no op1, then the
  1440. * destination string number is assumed to be in the xreg.
  1441.     MACRO
  1442. &lab    _readstr    &op
  1443. &lab    
  1444.     if    &op='' goto .jsr
  1445.     ldx    #<&op
  1446. .jsr    jsr    readstr
  1447.     MEND
  1448.  
  1449.  
  1450. ***************************************
  1451.  
  1452.  
  1453. * This macro is used to set the end-of-string character for _readstr.  If
  1454. * there is no op1, then the _readstr ending character is assumed to be in
  1455. * the acc.
  1456.     MACRO
  1457. &lab    _readend    &op
  1458. &lab    
  1459.     if    &op='' goto .jsr
  1460.     acorm    &op
  1461. .jsr    jsr    readend
  1462.     MEND
  1463.  
  1464.  
  1465. ***************************************
  1466. ***************************************
  1467. ***************************************
  1468.  
  1469.  
  1470. * This macro is used to define some memory as an array of up to
  1471. * 4 dimensions.  The first parameter is the location of the
  1472. * array, or where the location of the array is stored.  The second
  1473. * parameter is the size of the elements, (b)yte or (w)ord.  The 
  1474. * third parameter is the first dimension.  The macro and routines
  1475. * actually ignore this dimension, since it would only be used for
  1476. * range checking anyway.  The fourth through sixth parameters are
  1477. * optional.  The more parameters, the more dimensions in the array.
  1478.     MACRO
  1479. &lab    _array    &loc,&elesize,&op1,&op2,&op3,&op4
  1480. &lab    
  1481.     if    &loc='' goto .a
  1482.     aycorm    &loc
  1483.     if    ayisbyte=1 then
  1484.     ldy    #0
  1485.     endif
  1486. .a    jsr    arraybase
  1487.     if    &op4='' goto .b
  1488.     if    &substr(&op4,1,1)<>'#' then
  1489. .err    aerror    '_array:  dimensions must be constants --  parameter must be preceeded by a #'
  1490.     mexit
  1491.     endif
  1492. .b    if    &op3='' goto .c
  1493.     if    &substr(&op3,1,1)<>'#' goto .err
  1494. .c    if    &op2='' goto .d
  1495.     if    &substr(&op2,1,1)<>'#' goto .err
  1496. .d    if    &op1='' goto .e
  1497.     if    &substr(&op1,1,1)<>'#' goto .err
  1498. .e    if    &substr(&elesize,1,1)='b' goto .byte
  1499.     if    &substr(&elesize,1,1)='B' goto .byte
  1500.     if    &substr(&elesize,1,1)='w' goto .word
  1501.     if    &substr(&elesize,1,1)='W' goto .word
  1502.     aerror    '_array:  element size can only be byte or word (b,w)'
  1503. .word    if    &op4>'' goto .w4
  1504.     if    &op3>'' goto .w3
  1505.     if    &op2>'' goto .w2
  1506.     mexit
  1507. .w2    lda    #<&substr(&op2,2,999)*2
  1508.     ldy    #>&substr(&op2,2,999)*2
  1509.     jsr    dim1size
  1510.     mexit
  1511. .w3    lda    #<&substr(&op2,2,999)*&substr(&op3,2,999)*2
  1512.     ldy    #>&substr(&op2,2,999)*&substr(&op3,2,999)*2
  1513.     jsr    dim1size
  1514.     lda    #<&substr(&op3,2,999)*2
  1515.     ldy    #>&substr(&op3,2,999)*2
  1516.     jsr    dim2size
  1517.     mexit
  1518. .w4    lda    #<&substr(&op2,2,999)*&substr(&op3,2,999)*&substr(&op4,2,999)*2
  1519.     ldy    #>&substr(&op2,2,999)*&substr(&op3,2,999)*&substr(&op4,2,999)*2
  1520.     jsr    dim1size
  1521.     lda    #<&substr(&op3,2,999)*&substr(&op4,2,999)*2
  1522.     ldy    #>&substr(&op3,2,999)*&substr(&op4,2,999)*2
  1523.     jsr    dim2size
  1524.     lda    #<&substr(&op4,2,999)*2
  1525.     ldy    #>&substr(&op4,2,999)*2
  1526.     jsr    dim3size
  1527.     mexit
  1528. .byte    if    &op4>'' goto .b4
  1529.     if    &op3>'' goto .b3
  1530.     if    &op2>'' goto .b2
  1531. .b2    lda    #<&substr(&op2,2,999)
  1532.     ldy    #>&substr(&op2,2,999)
  1533.     jsr    dim1size
  1534.     mexit
  1535. .b3    lda    #<&substr(&op2,2,999)*&substr(&op3,2,999)
  1536.     ldy    #>&substr(&op2,2,999)*&substr(&op3,2,999)
  1537.     jsr    dim1size
  1538.     lda    #<&substr(&op3,2,999)
  1539.     ldy    #>&substr(&op3,2,999)
  1540.     jsr    dim2size
  1541.     mexit
  1542. .b4    lda    #<&substr(&op2,2,999)*&substr(&op3,2,999)*&substr(&op4,2,999)
  1543.     ldy    #>&substr(&op2,2,999)*&substr(&op3,2,999)*&substr(&op4,2,999)
  1544.     jsr    dim1size
  1545.     lda    #<&substr(&op3,2,999)*&substr(&op4,2,999)
  1546.     ldy    #>&substr(&op3,2,999)*&substr(&op4,2,999)
  1547.     jsr    dim2size
  1548.     lda    #<&substr(&op4,2,999)
  1549.     ldy    #>&substr(&op4,2,999)
  1550.     jsr    dim3size
  1551.     MEND
  1552.  
  1553.  
  1554. ***************************************
  1555.  
  1556.  
  1557. * This macro is used to index into the current array (defined by _array).
  1558. * The whole goal of the array handling is to index down to the row level.
  1559. * Once at the row level, you use the right-most subscript to index into
  1560. * that row.  This makes working on a row very fast, since all subscripts
  1561. * are not involved each time.  So, _index would be used for all subscripts
  1562. * except for the last subscript.  The parameter can either be a constant,
  1563. * (preceeded with a #) or can be a location in ram that holds the index
  1564. * (preceeded with an *).
  1565.     MACRO
  1566. &lab    _index    &op1,&op2,&op3
  1567. &lab
  1568.     if    &op1='' goto .a
  1569.     aycorm    &op1
  1570.     if    ayisbyte=1 then
  1571.     jsr    arraylindx1
  1572.     else
  1573.     jsr    arrayindx1
  1574.     endif
  1575. .a    if    &op2='' goto .b
  1576.     aycorm    &op2
  1577.     if    ayisbyte=1 then
  1578.     jsr    arraylindx2
  1579.     else
  1580.     jsr    arrayindx2
  1581.     endif
  1582. .b    if    &op3='' goto .c
  1583.     aycorm    &op3
  1584.     if    ayisbyte=1 then
  1585.     jsr    arraylindx3
  1586.     else
  1587.     jsr    arrayindx3
  1588.     endif
  1589. .c    MEND
  1590.  
  1591.  
  1592. ***************************************
  1593.  
  1594.  
  1595. * This macro works the same as _index, except that the index is stored
  1596. * in the variable indicated.
  1597.     MACRO
  1598. &lab    _vindex    &op1,&op2,&op3
  1599. &lab
  1600.     if    &op1='' goto .a
  1601.     ldy    #<&op1
  1602.     jsr    varyindx1
  1603. .a    if    &op2='' goto .b
  1604.     ldy    #<&op2
  1605.     jsr    varyindx2
  1606. .b    if    &op3='' goto .c
  1607.     ldy    #<&op3
  1608.     jsr    varyindx3
  1609. .c    MEND
  1610.  
  1611.  
  1612. ***************************************
  1613.  
  1614.  
  1615. * This macro gets a byte from the working row of the current array.
  1616. * The final index parameter is used to index into this row.
  1617.     MACRO
  1618. &lab    _getb    &op1,&op2
  1619. &lab
  1620.     if    &op1='' goto .a
  1621.     ldx    #<&op1
  1622. .a    if    &op2='' goto .jsr
  1623.     aycorm    &op2
  1624.     if    ayisbyte=1 then
  1625.     jsr    getbytel
  1626.     mexit
  1627.     endif
  1628. .jsr    jsr    getbyte
  1629.     MEND
  1630.  
  1631.  
  1632. ***************************************
  1633.  
  1634.  
  1635. * This macro gets a byte from the working row of the current array.
  1636. * The final index parameter is used to index into this row.
  1637.     MACRO
  1638. &lab    _getbl    &op1,&op2
  1639. &lab
  1640.     if    &op1='' goto .a
  1641.     ldx    #<&op1
  1642. .a    if    &op2='' goto .jsr
  1643.     acorm    &op2
  1644. .jsr    jsr    getbytel
  1645.     MEND
  1646.  
  1647.  
  1648. ***************************************
  1649.  
  1650.  
  1651. * This macro is works the same as _getb, except that the index is
  1652. * stored in a variable.
  1653.     MACRO
  1654. &lab    _vgetb    &op1,&op2
  1655. &lab
  1656.     if    &op1='' goto .a
  1657.     ldx    #<&op1
  1658. .a    if    &op2='' goto .jsr
  1659.     ldy    #<&op2
  1660. .jsr    jsr    vgetbyte
  1661.     MEND
  1662.  
  1663.  
  1664. ***************************************
  1665.  
  1666.  
  1667. * This macro is the same as _getb, except that it gets a word.
  1668.     MACRO
  1669. &lab    _getw    &op1,&op2
  1670. &lab
  1671.     if    &op1='' goto .a
  1672.     ldx    #<&op1
  1673. .a    if    &op2='' goto .jsr
  1674.     aycorm    &op2
  1675.     if    ayisbyte=1 then
  1676.     jsr    getwordl
  1677.     mexit
  1678.     endif
  1679. .jsr    jsr    getword
  1680.     MEND
  1681.  
  1682.  
  1683. ***************************************
  1684.  
  1685.  
  1686. * This macro is the same as _getb, except that it gets a word.
  1687.     MACRO
  1688. &lab    _getwl    &op1,&op2
  1689. &lab
  1690.     if    &op1='' goto .a
  1691.     ldx    #<&op1
  1692. .a    if    &op2='' goto .jsr
  1693.     acorm    &op2
  1694. .jsr    jsr    getwordl
  1695.     MEND
  1696.  
  1697.  
  1698. ***************************************
  1699.  
  1700.  
  1701. * This macro is the same as _vgetb, except that it gets a word.
  1702.     MACRO
  1703. &lab    _vgetw    &op1,&op2
  1704. &lab
  1705.     if    &op1='' goto .a
  1706.     ldx    #<&op1
  1707. .a    if    &op2='' goto .jsr
  1708.     ldy    #<&op2
  1709. .jsr    jsr    vgetword
  1710.     MEND
  1711.  
  1712.  
  1713. ***************************************
  1714.  
  1715.  
  1716. * This macro is the same as _getb, except that it stores a byte.
  1717.     MACRO
  1718. &lab    _putb    &op1,&op2
  1719. &lab
  1720.     if    &op1='' goto .a
  1721.     ldx    #<&op1
  1722. .a    if    &op2='' goto .jsr
  1723.     aycorm    &op2
  1724.     if    ayisbyte=1 then
  1725.     jsr    putbytel
  1726.     mexit
  1727.     endif
  1728. .jsr    jsr    putbyte
  1729.     MEND
  1730.  
  1731.  
  1732. ***************************************
  1733.  
  1734.  
  1735. * This macro is the same as _getb, except that it stores a byte.
  1736.     MACRO
  1737. &lab    _putbl    &op1,&op2
  1738. &lab
  1739.     if    &op1='' goto .a
  1740.     ldx    #<&op1
  1741. .a    if    &op2='' goto .jsr
  1742.     acorm    &op2
  1743. .jsr    jsr    putbytel
  1744.     MEND
  1745.  
  1746.  
  1747. ***************************************
  1748.  
  1749.  
  1750. * This macro is the same as _vgetb, except that it stores a byte.
  1751.     MACRO
  1752. &lab    _vputb    &op1,&op2
  1753. &lab
  1754.     if    &op1='' goto .a
  1755.     ldx    #<&op1
  1756. .a    if    &op2='' goto .jsr
  1757.     ldy    #<&op2
  1758. .jsr    jsr    vputbyte
  1759.     MEND
  1760.  
  1761.  
  1762. ***************************************
  1763.  
  1764.  
  1765. * This macro is the same as _getw, except that it stores a word.
  1766.     MACRO
  1767. &lab    _putw    &op1,&op2
  1768. &lab
  1769.     if    &op1='' goto .a
  1770.     ldx    #<&op1
  1771. .a    if    &op2='' goto .jsr
  1772.     aycorm    &op2
  1773.     if    ayisbyte=1 then
  1774.     jsr    putwordl
  1775.     mexit
  1776.     endif
  1777. .jsr    jsr    putword
  1778.     MEND
  1779.  
  1780.  
  1781. ***************************************
  1782.  
  1783.  
  1784. * This macro is the same as _getw, except that it stores a word.
  1785.     MACRO
  1786. &lab    _putwl    &op1,&op2
  1787. &lab
  1788.     if    &op1='' goto .a
  1789.     ldx    #<&op1
  1790. .a    if    &op2='' goto .jsr
  1791.     acorm    &op2
  1792. .jsr    jsr    putwordl
  1793.     MEND
  1794.  
  1795.  
  1796. ***************************************
  1797.  
  1798.  
  1799. * This macro is the same as _vgetw, except that it stores a word.
  1800.     MACRO
  1801. &lab    _vputw    &op1,&op2
  1802. &lab
  1803.     if    &op1='' goto .a
  1804.     ldx    #<&op1
  1805. .a    if    &op2='' goto .jsr
  1806.     ldy    #<&op2
  1807. .jsr    jsr    vputword
  1808.     MEND
  1809.